Loading header...

Counters: Asynchronous and Synchronous

Learning Objectives

By the end of this lesson, you should be able to:

  • describe what a digital counter stores and outputs;
  • calculate counter modulus, bit width, and output frequency division;
  • compare asynchronous ripple counters with synchronous counters;
  • design small up, down, and modulo-N counters;
  • recognize glitches, reset hazards, and timing limits;
  • verify counter behavior in hardware or HDL simulation.

What Is a Counter?

A counter is a sequential circuit that steps through a defined state sequence on clock events.

For an n-bit binary counter:

number of states = 2^n
count range = 0 to 2^n - 1

Example: a 4-bit counter has 2^4 = 16 states, from 0000 to 1111.

Counters are used for:

  • event counting;
  • timers and delays;
  • frequency division;
  • address generation;
  • state sequencing;
  • baud-rate and sampling clocks.

Frequency Division

Each bit of a binary counter divides the input clock by a power of two.

Counter bit Toggle rate
Q0 fclk / 2
Q1 fclk / 4
Q2 fclk / 8
Q3 fclk / 16

General formula:

f(Qk) = fclk / 2^(k + 1)

where Q0 is the least significant bit.

Asynchronous Ripple Counter

In an asynchronous, or ripple, counter, the first flip-flop is clocked by the external clock. Each following flip-flop is clocked by the previous stage.

flowchart LR CLK["CLK"] --> F0["TFF Q0"] F0 --> F1["TFF Q1"] F1 --> F2["TFF Q2"] F2 --> F3["TFF Q3"]

The output changes ripple from one stage to the next.

title "Ripple counter delay sketch"
time start=0 end=80 unit=ns divisions=8

CLK: square label="CLK" low=0 high=1 duty=50 cycles=4 unit=logic color=#2563eb
Q0: square label="Q0 delay after CLK" low=0 high=1 duty=50 cycles=2 phase=10 unit=logic color=#16a34a
Q1: square label="Q1 delay after Q0" low=0 high=1 duty=50 cycles=1 phase=20 unit=logic color=#dc2626
marker EDGE at=20 label="edge"
marker RIPPLE at=26 label="ripple settles"

This waveform is illustrative. Actual ripple delay depends on flip-flop propagation delay and loading.

Ripple Counter Advantages

  • simple to build from toggle flip-flops;
  • low gate count;
  • useful for low-speed frequency division.

Ripple Counter Limitations

  • outputs do not change at the same time;
  • decoded outputs can glitch during ripple transitions;
  • maximum clock speed falls as more stages are added;
  • poor fit for high-speed synchronous systems.

Approximate worst-case ripple delay:

t_settle = n * tpd_flipflop

where n is the number of stages.

Synchronous Counter

In a synchronous counter, all flip-flops share the same clock. Combinational logic calculates each next state.

flowchart LR Q["Present count Q"] --> L["Next-state logic"] L --> D["D inputs"] CLK["Common CLK"] --> R["Counter register"] D --> R R --> Q

Because all bits update on the same clock edge, synchronous counters are preferred for CPUs, FPGAs, CPLDs, and timing-critical digital systems.

For a 3-bit binary up counter using T flip-flop behavior:

Bit Toggle condition
Q0 always toggles
Q1 toggles when Q0 = 1
Q2 toggles when Q1 Q0 = 11

Using D flip-flops, you normally describe the counter as:

always @(posedge clk) begin
  if (rst) begin
    count <= 3'b000;
  end else begin
    count <= count + 3'b001;
  end
end

The synthesis tool builds the required next-state logic.

Up, Down, and Up-Down Counters

An up counter increments:

000, 001, 010, 011, 100, ...

A down counter decrements:

111, 110, 101, 100, 011, ...

An up-down counter chooses direction with a control signal.

always @(posedge clk) begin
  if (rst) begin
    count <= 4'd0;
  end else if (up) begin
    count <= count + 4'd1;
  end else begin
    count <= count - 4'd1;
  end
end

Unsigned counters wrap naturally after their maximum value.

Modulo-N Counters

A modulo-N counter has N states before repeating.

Examples:

Counter States Notes
MOD-10 decade 0 to 9 BCD counting
MOD-12 0 to 11 clock hours or sequence logic
MOD-60 0 to 59 seconds or minutes

Minimum bit width:

bits = ceiling(log2(N))

For MOD-10:

ceiling(log2(10)) = 4 bits

Four bits provide 16 possible states, so states 10 to 15 must be unused or corrected.

Safe MOD-10 HDL

always @(posedge clk) begin
  if (rst) begin
    count <= 4'd0;
  end else if (count == 4'd9) begin
    count <= 4'd0;
  end else begin
    count <= count + 4'd1;
  end
end

This synchronous version avoids glitchy asynchronous reset decoding.

Decoding Counter States

Decoding a counter state means detecting a particular binary value.

Example: detect count 9 (1001):

terminal_count = Q3 Q2' Q1' Q0

Use decoded terminal-count signals carefully:

  • register them when they drive important enables;
  • avoid using a ripple counter decode as a clock;
  • consider whether the decoded pulse is one full clock cycle or only a narrow combinational pulse.

Worked Example: Create a 1 kHz Tick From 1 MHz

Goal: generate a one-clock-wide tick every 1 ms from a 1 MHz clock.

Clock period:

Tclk = 1 / 1 MHz = 1 us

Needed counts:

1 ms / 1 us = 1000 counts

Use a MOD-1000 counter. Bit width:

ceiling(log2(1000)) = 10 bits

Verilog:

reg [9:0] count;
reg tick;

always @(posedge clk) begin
  if (rst) begin
    count <= 10'd0;
    tick <= 1'b0;
  end else if (count == 10'd999) begin
    count <= 10'd0;
    tick <= 1'b1;
  end else begin
    count <= count + 10'd1;
    tick <= 1'b0;
  end
end

Expected behavior: tick is high for one clock cycle every 1000 input clocks.

Johnson and Ring Counters

A ring counter circulates a single 1 through a shift register:

0001 -> 0010 -> 0100 -> 1000 -> 0001

A Johnson counter feeds the inverted last output back to the first input:

0000 -> 0001 -> 0011 -> 0111 -> 1111 -> 1110 -> 1100 -> 1000 -> 0000

Ring counters are simple one-hot sequencers. Johnson counters produce 2n states from n flip-flops and can simplify decoding.

Practical Hardware Notes

  • Debounce mechanical clock inputs before counting them.
  • Use a Schmitt-trigger input for slow or noisy external pulses.
  • Do not build high-speed clock trees from ripple counter outputs.
  • In FPGA designs, use clock-enable pulses instead of divided clocks unless the clocking resources are designed for division.
  • Include reset or self-correction for counters with unused states.

Common Mistakes

Mistake Symptom Fix
Using ripple output as a clean bus transient wrong decoded values use synchronous counters
Asynchronous decode reset for MOD-N narrow glitches or missed reset use synchronous terminal-count logic
Wrong bit-width calculation counter wraps too early use ceiling(log2(N))
Button connected as clock multiple counts per press debounce and synchronize
Divided FPGA clock used casually timing and CDC problems use clock enable or clock manager

Verification Checklist

  • Simulate reset, first count, terminal count, and wraparound.
  • Confirm count sequence includes exactly the intended states.
  • Check terminal-count pulse width.
  • Check fout = fclk / division_ratio.
  • Check timing report for synchronous implementations.
  • On hardware, probe clock, reset, count bits, and terminal-count output together.

Summary

Counters are flip-flop based state machines that step through numeric or symbolic sequences. Ripple counters are simple but have staged delays and glitch risks. Synchronous counters update all bits on the same clock edge and are the normal choice for reliable digital design. Modulo-N counters need enough bits plus correct terminal-count logic.

Further Reading

  • M. Morris Mano and Michael Ciletti, Digital Design
  • Texas Instruments datasheets for 74HC393, 74HC161, 74HC163, and 74HC190
  • FPGA vendor clocking and clock-enable design guides
  • Stephen Brown and Zvonko Vranesic, Fundamentals of Digital Logic with Verilog Design

Mind Map

mindmap root((Counters)) Core idea Sequential state sequence Counts events or clocks Stores count in flip flops Formulas States equal 2 to n Range 0 to 2 to n minus 1 Bits equal ceiling log2 N Qk frequency equals fclk over 2 to k plus 1 Ripple settle equals n times tpd Types Ripple simple low speed Synchronous shared clock Up and down Modulo N Ring and Johnson Design rules Prefer synchronous for logic Register decoded enables Reset unused states Use clock enables in FPGA Practical checks Verify exact sequence Check wrap point Measure terminal pulse width Read timing report Debounce external pulses Common mistakes Glitchy ripple decode Wrong bit width Button bounce counts Divided clock CDC issue Async reset decode hazards